using System.Collections.Generic;
using System.Text;
using UnityEngine;

/// <summary>
/// StringBuilder对象池 - 用于减少GC分配
/// </summary>
public static class StringBuilderPool
{
    private static readonly Stack<StringBuilder> s_Pool = new Stack<StringBuilder>();
    private const int MAX_POOL_SIZE = 50; // 限制池大小，防止过度内存使用
    private const int DEFAULT_CAPACITY = 256; // 默认容量

    /// <summary>
    /// 从池中获取一个StringBuilder
    /// </summary>
    /// <returns>可用的StringBuilder实例</returns>
    public static StringBuilder Get()
    {
        if (s_Pool.Count > 0)
        {
            var sb = s_Pool.Pop();
            sb.Clear(); // 清空内容
            return sb;
        }
        return new StringBuilder(DEFAULT_CAPACITY);
    }

    /// <summary>
    /// 从池中获取一个StringBuilder，并设置初始容量
    /// </summary>
    /// <param name="capacity">初始容量</param>
    /// <returns>可用的StringBuilder实例</returns>
    public static StringBuilder Get(int capacity)
    {
        if (s_Pool.Count > 0)
        {
            var sb = s_Pool.Pop();
            sb.Clear(); // 清空内容
            sb.Capacity = Mathf.Max(sb.Capacity, capacity);
            return sb;
        }
        return new StringBuilder(Mathf.Max(DEFAULT_CAPACITY, capacity));
    }

    /// <summary>
    /// 将StringBuilder归还到池中
    /// </summary>
    /// <param name="sb">要归还的StringBuilder</param>
    public static void Return(StringBuilder sb)
    {
        if (sb == null) return;

        // 清空StringBuilder以防止数据残留
        sb.Clear();
        
        // 如果池未满，则归还到池中
        if (s_Pool.Count < MAX_POOL_SIZE)
        {
            s_Pool.Push(sb);
        }
        // 如果池已满，让StringBuilder被垃圾回收
    }

    /// <summary>
    /// 获取池中可用的StringBuilder数量
    /// </summary>
    public static int PoolCount => s_Pool.Count;

    /// <summary>
    /// 清空对象池
    /// </summary>
    public static void Clear()
    {
        s_Pool.Clear();
    }

    /// <summary>
    /// 获取池的统计信息
    /// </summary>
    /// <returns>池的统计信息字符串</returns>
    public static string GetPoolStatistics()
    {
        return $"StringBuilderPool: {s_Pool.Count}/{MAX_POOL_SIZE} available";
    }
}
